package cs304.p3.library.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import cs304.p3.library.controller.ClerkController;
import cs304.p3.library.domain.BookCopy;
import cs304.p3.library.domain.Borrower;
import cs304.p3.library.framework.IoC;
import cs304.p3.library.framework.ViewResolver;
import cs304.p3.library.util.FixedSizeNumberDocument;
import cs304.p3.library.util.SqlUtils;

@SuppressWarnings("serial")
public class ClerkDialog extends JDialog{
	
	private MainFrame parent;
	private JTabbedPane tabbedPane;
	private JPanel addBorrowerPanel, checkOutPanel, returnPanel, checkOverduePanel;
	private ClerkController clerkController;
	
	private JTextField nameField, addrField, phoneField, emailField, sinField, expField, checkoutBIDField, returnCallField, returnCopyField;
	private JComboBox typeComboBox;
	private JList bookList, overdueList;
	
	public ClerkDialog(MainFrame frame, String title){
		super(frame, title);
		parent = frame;
		setLayout(new BorderLayout());
		tabbedPane = new JTabbedPane();
		
		//Setup controllers and forms
		clerkController = IoC.resolve(ClerkController.class);
		clerkController.setView(this);
		
		//Construct the tabs and their panels
		GridBagLayout gb = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		
		//Borrower Tab
		addBorrowerPanel = new JPanel();
		addBorrowerPanel.setLayout(gb);
		addBorrowerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		//Create the components
		JLabel nameLabel, addrLabel, phoneLabel, emailLabel, sinLabel, expLabel, typeLabel;
		nameLabel = new JLabel("Name: ");
		addrLabel = new JLabel("Address: ");
		phoneLabel = new JLabel("Phone Number: ");
		emailLabel = new JLabel("email: ");
		sinLabel = new JLabel("Sin/Std No. : ");
		expLabel = new JLabel("Expiry Date: ");
		typeLabel = new JLabel("Borrower Type: ");
		nameField = new JTextField(8);
		addrField = new JTextField(8);
		phoneField = new JTextField(8);
		phoneField.setDocument(new FixedSizeNumberDocument(phoneField,10));
		emailField = new JTextField(8);
		sinField = new JTextField(8);
		sinField.setDocument(new FixedSizeNumberDocument(sinField,10));
		expField = new JTextField(8);
		expField.setText(SqlUtils.getDateString(new Date()));
		typeComboBox = new JComboBox(new DefaultComboBoxModel(clerkController.getService().getBorrowerTypes().keySet().toArray()));
		//Add to the panel
		//Name
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(nameLabel, c);
		addBorrowerPanel.add(nameLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(nameField, c);
		addBorrowerPanel.add(nameField);
		//Address
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(addrLabel, c);
		addBorrowerPanel.add(addrLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(addrField, c);
		addBorrowerPanel.add(addrField);
		//Phone
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(phoneLabel, c);
		addBorrowerPanel.add(phoneLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(phoneField, c);
		addBorrowerPanel.add(phoneField);
		//email
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(emailLabel, c);
		addBorrowerPanel.add(emailLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(emailField, c);
		addBorrowerPanel.add(emailField);
		//sin/student no
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(sinLabel, c);
		addBorrowerPanel.add(sinLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(sinField, c);
		addBorrowerPanel.add(sinField);
		//Exp. Date
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(expLabel, c);
		addBorrowerPanel.add(expLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(expField, c);
		addBorrowerPanel.add(expField);
		//Borrower Type
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(typeLabel, c);
		addBorrowerPanel.add(typeLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(typeComboBox, c);
		addBorrowerPanel.add(typeComboBox);
		//Add action button
		JButton addBorrowerButton = new JButton("Add");
		addBorrowerButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				String email = emailField.getText();
				if(email.isEmpty() || !email.contains("@")){
					IoC.displayUserInvalidInputMessage("Must enter a valid email!");
				}else{
					Borrower b = clerkController.getBorrower();
					b.setName(nameField.getText());
					b.setAddress(addrField.getText());
					b.setPhone(phoneField.getText());
					b.setEmailAddress(emailField.getText());
					b.setSinOrStNo(sinField.getText());
					b.setExpiryDate(SqlUtils.getDate(expField.getText()));
					b.setType((String)typeComboBox.getSelectedItem());
					clerkController.performAddBorrowerAction();
					parent.updateDBTables();
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(addBorrowerButton, c);
		addBorrowerPanel.add(addBorrowerButton);
		
		//--------------------------------------------------------------
		//Checkout Tab
		checkOutPanel = new JPanel();
		checkOutPanel.setLayout(new BorderLayout());
		//Setup control panel
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		JPanel checkOutControlPanel = new JPanel();
		checkOutControlPanel.setLayout(gb);
		checkOutControlPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		checkOutPanel.add(checkOutControlPanel, BorderLayout.CENTER);
		//Add components
		JLabel checkoutBID = new JLabel("Borrower ID: ");
		checkoutBIDField = new JTextField(8);
		checkoutBIDField.setDocument(new FixedSizeNumberDocument(checkoutBIDField, 8));
		//BID
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(checkoutBID, c);
		checkOutControlPanel.add(checkoutBID);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(checkoutBIDField, c);
		checkOutControlPanel.add(checkoutBIDField);
		//Add Book button
		JButton addBookButton = new JButton("Add Book");
		addBookButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				ViewResolver.gotoCheckOutBookView();
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(addBookButton, c);
		checkOutControlPanel.add(addBookButton);
		//Remove Book button
		JButton removeBookButton = new JButton("Remove Book");
		removeBookButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				int index = bookList.getSelectedIndex();
				DefaultListModel model = (DefaultListModel) bookList.getModel();
				if(index > -1) model.remove(index);
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(removeBookButton, c);
		checkOutControlPanel.add(removeBookButton);
		//Finished button
		JButton finishButton = new JButton("Done");
		finishButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				clerkController.getClerk().setBID(checkoutBIDField.getText());
				clerkController.performCheckOutAction();
				parent.updateDBTables();
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(finishButton, c);
		checkOutControlPanel.add(finishButton);
		//Setup Book List view
		bookList = new JList(new DefaultListModel());
		bookList.setFont(new Font("Verdana", Font.PLAIN, 18));
		bookList.setFixedCellWidth(200);
		bookList.setPrototypeCellValue("12345678");
		JPanel listPanel = new JPanel();
		listPanel.setLayout(new BorderLayout());
		listPanel.add(new JScrollPane(bookList), BorderLayout.CENTER);
		listPanel.setMinimumSize(listPanel.getPreferredSize());
		listPanel.setMaximumSize(listPanel.getPreferredSize());
		checkOutPanel.add(listPanel, BorderLayout.EAST);
		
		//--------------------------------------------------------------
		//Return Tab
		returnPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		returnPanel.setLayout(gb);
		returnPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		//Add components
		JLabel returnCopyLabel = new JLabel("Copy Number: ");
		JLabel returnCallLabel = new JLabel("Call Number: ");
		returnCopyField = new JTextField(8);
		returnCopyField.setDocument(new FixedSizeNumberDocument(returnCopyField, 8));
		returnCallField = new JTextField(8);
		returnCallField.setDocument(new FixedSizeNumberDocument(returnCallField, 8));
		//Copy#
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(returnCopyLabel, c);
		returnPanel.add(returnCopyLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(returnCopyField, c);
		returnPanel.add(returnCopyField);
		//Call#
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(returnCallLabel, c);
		returnPanel.add(returnCallLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(returnCallField, c);
		returnPanel.add(returnCallField);
		//Return Button
		JButton returnButton = new JButton("Return");
		returnButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				clerkController.getClerk().setReturnCallNumber(returnCallField.getText());
				clerkController.getClerk().setReturnCopyNumber(returnCopyField.getText());
				clerkController.performReturnAction();
				parent.updateDBTables();
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 20, 10, 10);
		gb.setConstraints(returnButton, c);
		returnPanel.add(returnButton);
		
		//--------------------------------------------------------------
		//Check Over Due Tab
		checkOverduePanel = new JPanel();
		checkOverduePanel.setLayout(new BorderLayout());
		overdueList = new JList(new DefaultListModel());
		overdueList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		checkOverduePanel.add(new JScrollPane(overdueList), BorderLayout.CENTER);
		//Control Panel
		JPanel overdueControlPanel = new JPanel();
		//Add reload button
		JButton overdueReload = new JButton("Refresh");
		overdueReload.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				clerkController.performOverdueRefreshAction();
				List<BookCopy> overdues = clerkController.getClerk().getOverdues();
				if(overdues != null){
					DefaultListModel model = (DefaultListModel) overdueList.getModel();
					model.clear();
					for(BookCopy copy : overdues){
						model.addElement(copy.toString());
					}
				}else IoC.displayCompleteMessage("No Overdues");
			}
			
		});
		overdueControlPanel.add(overdueReload);
		checkOverduePanel.add(overdueControlPanel, BorderLayout.SOUTH);
		
		
		//Add the tabs
		tabbedPane.add(addBorrowerPanel, "Add Borrower");
		tabbedPane.add(checkOutPanel, "Check-Outs");
		tabbedPane.add(returnPanel, "Returns");
		tabbedPane.add(checkOverduePanel, "Check Overdues");
		
		//Add exit panel and button
		JPanel exitPanel = new JPanel();
		JButton exitButton = new JButton("Close");
		exitButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				ClerkDialog.this.setVisible(false);
				ClerkDialog.this.dispose();
			}
			
		});
		exitPanel.add(exitButton);
		add(exitPanel, BorderLayout.SOUTH);
		
		//finalize and show
		add(tabbedPane, BorderLayout.CENTER);
		pack();
		setResizable(false);
		Point loc = frame.getLocationOnScreen();
		Dimension d = frame.getSize();
		setLocation(loc.x + (d.width - getWidth())/2, loc.y + (d.height - getHeight())/2);
	  	setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	    setVisible(true);
	}
	
	public void clearAddBorrowerFields(){
		nameField.setText("");
		addrField.setText("");
		phoneField.setText("");
		emailField.setText("");
		sinField.setText("");
	}
	
	public void clearCheckOutFields(){
		checkoutBIDField.setText("");
		((DefaultListModel)bookList.getModel()).clear();
	}
	
	public void clearReturnFields() {
		returnCallField.setText("");
		returnCopyField.setText("");
	}
	
	public void updateBookList(String book){
		DefaultListModel model = (DefaultListModel) bookList.getModel();
		model.addElement(book);
	}
	
}
